/*
	Copyright 2007-2010 Petr Ohlidal

	This file is a part of GrobMaker

	GrobMaker is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	GrobMaker is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with GrobMaker.  If not, see <http://www.gnu.org/licenses/>.
*/

/**
 * @file ArgParser.hpp
 * @brief Utility for command-line args parsing.
 */

#ifndef GROBMAKER_ARGPARSER
#define GROBMAKER_ARGPARSER

#include <cstring>

namespace GrobMaker{

/** Iterates args and helps to parse them.
*/
class ArgParser{
	char** mArgv;
	int mArgc;
	int mCurrentArg;

	public:

	ArgParser(int argc, char** argv)
		:mArgv(argv), mArgc(argc), mCurrentArg(1){
	}

	bool hasNext() const{
		return mCurrentArg<mArgc;
	}

	/** Iterates to next arg.
	* @return False if there are no more args.
	*/
	bool goNext(){
		if(!this->hasNext()){
			return false;
		}else{
			mCurrentArg++;
			return true;
		}
	}

	/** Checks if the arg is a long param (--help for example)
	* @param value Name to check. Empty string = no name checking.
	* @return True if arg is a short param, false if not.
	*         If name is specified, true if matches, false if not.
	*/
	bool checkLongParam(const std::string& name = std::string()) const{
		if(std::strlen(mArgv[mCurrentArg])>=2 && mArgv[mCurrentArg][0] == '-' && mArgv[mCurrentArg][1] == '-'){
			// Long param
			if(name.empty()){
				return true;
			}else if(std::strcmp(&mArgv[mCurrentArg][2],name.c_str()) == 0){
				return true;
			}else{
				return false;
			}
		}else{
		// No param
		return false;
		}
	}

	/** Checks if the arg is a short param (-h for example)
	* @param value Name to check. Empty string = no name checking.
	* @return True if arg is a short param, false if not.
	*         If name is specified, true if matches, false if not.
	*/
	bool checkShortParam(char name) const{
		if(std::strlen(mArgv[mCurrentArg])>1 && mArgv[mCurrentArg][0] == '-' && mArgv[mCurrentArg][1]!='-' ){
			// Short param
			for(unsigned int i=1; i<std::strlen(mArgv[mCurrentArg]); i++){
				if(mArgv[mCurrentArg][i]==name){
					return true;
				}
			}
			return false;
		}else{
			// No param
			return false;
		}
	}

	int getAsInteger() const{
		return atoi(mArgv[mCurrentArg]);
	}

	const char* getArg() const{
		return mArgv[mCurrentArg];
	}

	const char* getAndGoNext(){
		const char* ret = this->getArg();
		this->goNext();
		return ret;
	}

	const char* getNextAndSkip(){
		this->goNext();
		return this->getAndGoNext();
	}

	int getArgIndex() const{
		return mCurrentArg;
	}

};

} // Namespace GrobMaker

#endif // Include guard
